"""Credits to:"""
#BlackJax96, jcao219, Random Talking Bush, Vile, Revel8n
#side credits: Roo525, AMKalmar, Bero
#low credits: Pharrox, Kryal

#mdl0 plugin v1.3a
def inf(support,im_types,ex_types,C_mthds): #plugin information
    support.append("*.mdl0") #supported import type
    im_types.append(('Wii','*.mdl0')) #individual import type
    #ex_types.append(('Wii','*.mdl0')) #individual export type
    C_mthds.append(['mdl0','Wii mdl0','im_mdl0','ex_mdl0']) #experimental
    #([ file_type , button_text, imbtn_name, exbtn_name ])
    
ex_debug = 0 #extended debugging mode

#--<<imports>>--
import NtdoCmn as NC
import Cmn as C #common functions
import GlobalTMP as G #TMP functions

def impt(imfl,imkey,debug): #import function
    if imfl.split(".")[-1] == "mdl0" and imkey == 'Wii mdl0': #check extension + safety check (requitred)
        fr = open(imfl,'rb') #open mdl0 file
        G.setWrite() #global.TMP to write
        NC.setFile(fr) #set the import file for NtdoCmn
        
        #settings
        glvcs = 0
        global trvcs
        trvcs = 0

        #--<<local functions>>--
        def name(offset): #returns a string of given length
            fr.seek((offset - 1), 0) #seek from start of file to string location
            str_len = C.ru8() #get the length of the string
            string = fr.read(str_len) #read the string
            return string #send the string back to where it's needed

        def List(offset): #returns the offsets in the group as a list
            fr.seek(offset, 0) #seek from start of file to the group offset
            group_list = [] #blank list var to be filled
            block_len = C.ru32() #get the length of the entire block
            num_offsets = C.ru32() #+ 1 #count the number of offsets in the group
            tmp = fr.read(16) # 'FFFF 0000 000# 000# 00000000 00000000 (old method)
            while num_offsets:
                num_offsets -= 1 #countdown method for offsets
                group_list.append(fr.read(16)) #fill the list with the offsets
            return group_list #send the filled list to it's location
        #--<<local functions>>--
        
        #<<header>>
        magic = fr.read(4)
        if magic == 'MDL0': #check if valad
            print 'MDL0 file is valad'
            #--header (part1)--
            strtbl_offset = C.ru32()
            version = C.ru32()
            
            if version == 9:
                nodes_offset = C.rs32()*(0-1)
                #list offsets to relocation table groups
                definits_list = C.ru32()
                bones_list = C.ru32()
                vertices_list = C.ru32()
                normals_list = C.ru32()
                colors_list = C.ru32()
                uv_points_list = C.ru32()
                materials_list = C.ru32()
                TEVs_list = C.ru32()
                objects_list = C.ru32()
                textures_list = C.ru32()
                pallets_list = C.ru32()
                #--header (part2)--
                string_offset = C.ru32() 
                header_length = C.ru32() #64
                header_offset = C.ru32()
                #--displayed in brawlbox:--
                unknown_1 = fr.read(4)
                unknown_2 = fr.read(4)
                NumVertices = C.ru32()
                NumFaces = C.ru32()
                unknown_3 = fr.read(4)
                NumNodes = C.ru32()
                unk_flags = C.rhex(fr.read(4))
                unknown_4 = fr.read(4)
                MinX,MinY,MinZ = C.rf(),C.rf(),C.rf()
                MaxX,MaxY,MaxZ = C.rf(),C.rf(),C.rf()
                NumNodes2 = fr.read(4) #(Copy?)
                
            elif version == 11:
                pass
                """
                unk_offset = C.rs32()*(0-1)
                #list offsets to relocation table groups
                definits_list = C.ru32()
                bones_list = C.ru32()
                vertices_list = C.ru32()
                normals_list = C.ru32()
                colors_list = C.ru32()
                uv_points_list = C.ru32()
                tmp1 = C.ru32()
                tmp2 = C.ru32()
                materials_list = C.ru32()
                TEVs_list = C.ru32()
                objects_list = C.ru32()
                textures_list = C.ru32()
                pallets_list = C.ru32()
                tmp3 = C.ru32()
                """
                
            else: print 'unrecognized MDL0 version'
            
        #<</header>>
            
            def vector(List, vec_offset, str_offset, ISvec3):
                string = name(List + str_offset)
                fr.seek(List + vec_offset, 0) #seek from start of file to header location
                
                #header
                block_size = C.ru32()
                MDL0_offset = C.rs32()*(0-1)
                data_offset = C.ru32() #usu 32 or 64(if bounds)
                string_offset = C.ru32()
                ID = C.ru32()
                bounds = C.ru32()
                data_type = C.ru32()
                multiplier = C.ru8()
                entry_stride = C.ru8()
                num_vectors = C.ru16()

                return NC.getNVector( data_type, multiplier, (List + vec_offset + data_offset), (num_vectors * entry_stride), ISvec3),ID
            
            #read process
            if definits_list:
                for offset in List(definits_list):
                    pass #saved for later
                    
            if bones_list:
                LASTX = []
                print;print 'Bones:'
                for offset in List(bones_list):
                    pass #saved for later
                    """
                    string = name(bones_list + C.rui(offset[8:12]))
                    fw.write('< bone '+string+' ')
                    if debug:print; print 'Name: ' + string
                    
                    def matrix():
                        #read the matrix from the mdl0
                        x1,y1,z1,o1 = C.rf()),C.rf()),C.rf()),C.rf())
                        x2,y2,z2,o2 = C.rf()),C.rf()),C.rf()),C.rf())
                        x3,y3,z3,o3 = C.rf()),C.rf()),C.rf()),C.rf())

                    fr.seek(bones_list+C.rui(offset[12:16]), 0) #seek from start of file to data location
                    block_size = C.ru32()
                    MDL0_offset = C.rs32()*(0-1)
                    string_offset = C.ru32()
                    bone_index = C.ru32()
                    node_ID = C.ru32()
                    flags = fr.read(4)
                    fr.read(8) #padding
                    #Loc,Rot,Sca
                    sX,sY,sZ = C.rf()),C.rf()),C.rf())
                    rX,rY,rZ = C.rf()),C.rf()),C.rf())
                    lX,lY,lZ = C.rf()),C.rf()),C.rf())
                    #bounds
                    MinX,MinY,MinZ = C.rf()),C.rf()),C.rf())
                    MaxX,MaxY,MaxZ = C.rf()),C.rf()),C.rf())
                    parent = C.rln(fr.read(4))/208
                    has_child = C.ru32()/208
                    Next_offset = C.ru32()/208
                    Prev_offset = C.rln(fr.read(4))/208
                    part2 = C.ru32()
                    
                    if len(LASTX) > 0: XPOS = LASTX[parent] + 1
                    else: XPOS = 0
                    LASTX.append(XPOS)
                    
                    if parent < (0-1): CONN = 0
                    else: CONN = 1
                    
                    fw.write(str(XPOS)+','+str(bone_index)+' '+str(CONN)+' '+\
                             str(lX)+','+str(lY)+','+str(lZ)+' '+\
                             str(rX)+','+str(rY)+','+str(rZ)+' '+\
                             str(sX)+','+str(sY)+','+str(sZ)+' ')
                        
                    bind = matrix()
                    
                    if debug: print 'inverse bind matrix:'
                    
                    inv_bind = matrix()
                    
                    fw.write('>\n')
                    """

            if vertices_list:
                for offset in List(vertices_list):
                    verticesList,objectID = vector(vertices_list, int(offset[12:16].encode('hex'),16), int(offset[8:12].encode('hex'),16), 1)
                    G.setVector( verticesList,0,0,objectID,0 )
                
            if normals_list:
                for offset in List(normals_list):
                    normalsList,objectID = vector(normals_list, int(offset[12:16].encode('hex'),16), int(offset[8:12].encode('hex'),16), 1)
                    G.setVector( normalsList,1,0,objectID,0 )
                
            if uv_points_list:
                for offset in List(uv_points_list):
                    uvsList,objectID = vector(uv_points_list, int(offset[12:16].encode('hex'),16), int(offset[8:12].encode('hex'),16), 0)
                    G.setVector( uvsList,2,0,objectID,0 )
                
            if colors_list:
                for offset in List(colors_list):
                    pass #saved for later
                    
            if materials_list:
                for offset in List(materials_list):
                    pass #saved for later
                    
            if TEVs_list:
                for offset in List(TEVs_list):
                    pass #saved for later
                    
            if objects_list:
                print;print 'Objects:';print
                
                for offset in List(objects_list):
                    string = name(objects_list + int(offset[8:12].encode('hex'),16))
                    if debug: print 'Name: ' + string; print
                    
                    fr.seek(objects_list+int(offset[12:16].encode('hex'),16), 0) #seek from start of file to data location
                    
                    block_size = C.ru32()
                    MDL0_offset = C.rs32()*(0-1)
                    node_index = C.ru32() # if(-1), use node tbl
                    CP_lo = C.ru32() #[] face-point format
                    CP_hi = C.ru32() #[] texture inputs
                    XF_spec = NC.XFNormalFormat(C.ru32()) #[] XF normal specs
                    attr_size = C.ru32() #Size of attr block (including padding)
                    attr_flags = C.ru32() # '00 00 00 80'
                    attr_offset = C.ru32()+32
                    data_len1 = C.ru32()
                    data_len2 = C.ru32() #(Copy?)
                    data_offset = C.ru32()+36
                    XF = NC.XFArrayFlags(C.ru32()) #face-point flags
                    unk = C.ru32()
                    string_offset = C.ru32()
                    ID = C.ru32()
                    num_verts = C.ru32()
                    num_faces = C.ru32()
                    pos_inp = C.ru16()
                    nor_inp = C.ru16()
                    
                    clr0_inp = C.ru16()
                    clr1_inp = C.ru16()
                    
                    uv0_inp = C.ru16()
                    uv1_inp = C.ru16()
                    uv2_inp = C.ru16()
                    uv3_inp = C.ru16()
                    uv4_inp = C.ru16()
                    uv5_inp = C.ru16()
                    uv6_inp = C.ru16()
                    uv7_inp = C.ru16()
                    node_tbl = C.ru32()


                    prmMatrices, FacePoints, Primitive_data = NC.getDisplayList(
                        NC.getCP_List(CP_lo,CP_hi), (objects_list+int(offset[12:16].encode('hex'),16)+data_offset), data_len1 )
                    PrimitivesList, Colors, FP_Matrices = NC.DList2PList( FacePoints, Primitive_data )
                    G.setObject(ID,string,'',[],PrimitivesList,[])

                    if XF[0] == 1: trvcs = 1
                    
            if textures_list:
                for offset in List(textures_list):
                    pass #saved for later
                    
            if pallets_list:
                for offset in List(pallets_list):
                    pass #saved for later

            trvcs = 0 #small hack
            #set specs
            settings = []
            if glvcs: settings.append('vecs_global')
            if trvcs: settings.append('vecs_transf')

            G.setSpecs(settings)
        
            #close all files no longer in use
            fr.close()
            G.closeWrite()
            
        else: #if file is invalad
            #close all files
            fr.close()
            G.closeWrite()
            print 'ERROR: not a valad MDL0 file'
            
def expt(exfl,exkey,debug): #export function
    #to be used later
    pass
